<?php

namespace App\Http\Controllers\Backstage\System;

use Validator;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Services\UserGroupService;
use App\Services\PartnerGroupTypeService;
use App\Services\CityService;
use App\Services\UserService;
use Illuminate\Validation\Rule;
use App\BaseDictionary;
use App\UserGroup;
use App\User;
use App\Lib\Auth\UserProfileHelper;

class GroupController extends Controller
{
    private $userGroupService = null;
    private $partnerGroupTypeService = null;
    private $userProfileHelper = null;
    private $userService = null;
    private $cityService = null;

    public function __construct(UserGroupService $userGroupService,
        PartnerGroupTypeService $partnerGroupTypeService,
        UserService $userService,
        CityService $cityService,
        UserProfileHelper $userProfileHelper)
    {
        $this->userGroupService = $userGroupService;
        $this->partnerGroupTypeService = $partnerGroupTypeService;
        $this->userProfileHelper = $userProfileHelper;
        $this->cityService = $cityService;
        $this->userService = $userService;
    }

    public function getCurrentUserGroup()
    {
        $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();

        if (!empty($managedGroupsInfo)) {
            $currentUserGroupId = $managedGroupsInfo['currentUserGroupId'];
            $managedGroups = $managedGroupsInfo['managedGroups'];
            $managedGroupIds = collect($managedGroups)->pluck('id')->toArray();
            $managedUsers = $this->userService->getUsersByGroups($managedGroupIds);
            return view('backstage.system.group.main_group', [
                'currentUserGroup' => $this->userGroupService->getCurrentUserGroup($currentUserGroupId),
                'managedUsers' => collect($managedUsers)->toArray()
            ]);
        } else {
            return view('backstage.system.group.main_group', [
                'managedUsers' => []
            ]);
        }
    }

    public function saveCurrentUserGroup(Request $request)
    {
        $input = $request->all();
        $this->validateWhenSaveCurrentGroup($input);

        $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();
        if (!empty($managedGroupsInfo)) {
            $userGroup = UserGroup::findOrFail($managedGroupsInfo['currentUserGroupId']);
        }

        //这里为了避免安全隐患（可以通过在$input里伪造business_code以及status达到越权的目的）
        //因此需要将客户端上传过来的数据全部按字段存储进去，而不要使用$userGroup->update($input)这种简化方法
        $userGroup->update([
            'id' => $userGroup->id,
            'name' => $input['name'],
            'icon' => $input['icon'],
            'manager_id' => $input['manager_id'],
            'province_id' => $input['province_id'],
            'city_id' => $input['city_id'],
            'district_id' => $input['district_id'],
            'detailed_address' => $input['detailed_address'],
        ]);

        return response()->json([
            'Success' => true,
            'Message' => '保存当前运营组织成功',
        ]);
    }

    public function indexOrg()
    {
        return view('backstage.system.group.department');
    }

    public function getInitOrgTrees()
    {
        return $this->userGroupService->getCascadeInternalGroups();
    }

    public function getDepartmentGroups(Request $request)
    {
        return $this->userGroupService
            ->getGroups($request->all());
    }

    public function createDepartment($parentId)
    {
        $parent = UserGroup::findOrFail($parentId);

        return view('backstage.system.group.create_dept', [
            'parent' => $parent,
            'groupManagerMandory' => false,
            'possiableParents' => $this->userGroupService->getPossiableParentGroups($parent),
            'managedUsers' => []
        ]);
    }

    public function saveNewDepartment(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNewDepartment($input);

        //为了确保安全，这里没有采用直接UserGroup::create($input)的方式
        UserGroup::create([
            'name' => $input['name'],
            'code' => $this->userGroupService->getNewChildGroupCode($input['parent_id']),
            'group_type' => $input['group_type'],
            'parent_id' => $input['parent_id'],
            'sort_order' => $input['sort_order'],
            'active_status' => UserGroup::$GROUP_STATUS_ACTIVE,
        ]);

        return response()->json([
            'Success' => true,
            'Message' => '新增内部部门组织成功',
        ]);
    }

    public function editDepartment($groupId)
    {
        $departGroup = UserGroup::findOrFail($groupId);
        $parent = $departGroup->parent;

        $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();
        $arrManagedGroups = $managedGroupsInfo['managedGroups'];
        $countManagedGroups = count($arrManagedGroups);
        for ($i=0; $i<$countManagedGroups; $i++) {
            if ($arrManagedGroups[$i]->id == $groupId) {
                unset($arrManagedGroups[$i]);
                break;
            }
        }
        $possiableParents = collect(array_values($arrManagedGroups));

        return view('backstage.system.group.create_dept', [
            'parent' => $parent,
            'groupManagerMandory' => false,
            'possiableParents' => $possiableParents,
            'managedUsers' => $departGroup->managedUsers()->where('user_active', User::$USER_STATUS_ACTIVE)->get(),
            'currentUserGroup' => $departGroup
        ]);
    }

    public function updateDepartment(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdateDepartment($input);

        $currentDepartment = UserGroup::findOrFail($input['id']);

        $data = [
            'id' => $input['id'],
            'name' => $input['name'],
            'group_type' => $input['group_type'],
            'parent_id' => $input['parent_id'],
            'sort_order' => $input['sort_order'],
        ];

        if (!empty($input['manager_id'])) {
            $data['manager_id'] = $input['manager_id'];
        }

        //父机构有改变，需要修改code
        if ($input['parent_id'] != $currentDepartment->parent_id) {
            $data['code'] = $this->userGroupService->getNewChildGroupCode($input['parent_id']);
        }

        $currentDepartment->update($data);

        return response()->json([
            'Success' => true,
            'Message' => '修改内部部门组织成功',
        ]);
    }

    public function deleteDepartment(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDeleteDepartment($input);

        $department = UserGroup::findOrFail($input['id']);
        $department->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除部门成功',
        ]);
    }

    public function indexExternalGroup()
    {
        return view('backstage.system.group.partner_org', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
            ], false)
        ]);
    }

    public function getExternalPartnerGroups(Request $request)
    {
        return $this->userGroupService
            ->getGroups(array_merge($request->all(), [
                'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE,
                'parentId'=>''
            ]));
    }

    public function createPartnerGroup()
    {
        return view('backstage.system.group.create_partner_org', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
            ], false)
        ]);
    }

    public function saveNewPartnerGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNewPartnerGroup($input);

        $this->userGroupService->saveNewPartnerGroupWithManager(array_merge($request->all(), [
            'sort_order' => 0,
            'active_status'=> UserGroup::$GROUP_STATUS_ACTIVE
        ]), UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE);

        return response()->json([
            'Success' => true,
            'Message' => '新增合作伙伴成功',
        ]);
    }

    public function editPartnerGroup($groupId)
    {
        $partnerGroup = UserGroup::findOrFail($groupId);

        return view('backstage.system.group.create_partner_org', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
            ], false),
            'currentUserGroup' => $partnerGroup
        ]);
    }

    public function saveUpdatePartnerGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdatePartnerGroup($input);

        $this->userGroupService->saveUpdatePartnerGroupWithManager($request->all(), UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE);

        return response()->json([
            'Success' => true,
            'Message' => '修改外部合作伙伴成功',
        ]);
    }

    public function deletePartnerGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDeletePartnerGroup($input);

        $department = UserGroup::findOrFail($input['id']);
        $department->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除合作伙伴成功',
        ]);
    }

    public function indexSimpleGroup()
    {
        return view('backstage.system.group.people_group', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_USER
            ], false)
        ]);
    }

    public function getSimplePartnerGroups(Request $request)
    {
        return $this->userGroupService
            ->getGroups(array_merge($request->all(), [
                'groupType'=>UserGroup::$GROUP_TYPE_USER,
                'parentId'=>''
            ]));
    }

    public function createSimpleGroup() {
        return view('backstage.system.group.create_simple_org', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_USER
            ], false)
        ]);
    }

    public function saveNewSimpleGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveNewSimpleGroup($input);

        $this->userGroupService->saveNewPartnerGroupWithManager(array_merge($request->all(), [
            'sort_order' => 0,
            'active_status'=> UserGroup::$GROUP_STATUS_ACTIVE
        ]), UserGroup::$GROUP_TYPE_USER);

        return response()->json([
            'Success' => true,
            'Message' => '新增个人伙伴成功',
        ]);
    }

    public function editSimpleGroup($groupId)
    {
        $partnerGroup = UserGroup::findOrFail($groupId);

        return view('backstage.system.group.create_simple_org', [
            'partnerGroupTypes' => $this->partnerGroupTypeService->getPartnerGroupTypes([
                'groupType'=>UserGroup::$GROUP_TYPE_USER
            ], false),
            'currentUserGroup' => $partnerGroup
        ]);
    }

    public function saveUpdateSimpleGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenSaveUpdateSimpleGroup($input);

        $this->userGroupService->saveUpdatePartnerGroupWithManager($request->all(), UserGroup::$GROUP_TYPE_USER);

        return response()->json([
            'Success' => true,
            'Message' => '修改个人合作伙伴成功',
        ]);
    }

    public function deleteSimpleGroup(Request $request)
    {
        $input = $request->all();

        $this->validateWhenDeleteSimpleGroup($input);

        $department = UserGroup::findOrFail($input['id']);
        $department->delete();

        return response()->json([
            'Success' => true,
            'Message' => '删除个人合作伙伴成功',
        ]);
    }
    /**
    * 获得当前用户所在机构/用户组下所有管理的用户
    */
    private function getManagedUsers()
    {
        $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();

        if (isset($managedGroupsInfo)) {

            $managedGroupIds = collect($managedGroupsInfo['managedGroups'])->pluck('id')->toArray();

            return $this->userService->getUsersByGroups($managedGroupIds)->toArray();
        }

        return [];
    }

    private function validateWhenSaveCurrentGroup(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();

                    if (isset($managedGroupsInfo)) {
                        $currentUserGroupId = $managedGroupsInfo['currentUserGroupId'];

                        $currentUserGroup = $this->userGroupService->getCurrentUserGroup($currentUserGroupId);

                        if ($currentUserGroup->isExternalEnterprise() || $currentUserGroup->isInternalOrganization()) {
                            $query->where('name', $input['name'])->where('id', '<>', $currentUserGroup->id);
                        }
                    } else {
                        $query->where('name', $input['name']);
                    }
                })
            ],
            'icon' => 'max:200',
            'manager_id' => [
                'required',
                Rule::in(collect($this->getManagedUsers())->pluck('id')->toArray())
            ],
            'province_id' => 'required|numeric|exists:provinces,id',
            'city_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getProvinceCities($input['province_id'])->pluck('id')->toArray())
            ],
            'district_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getCityDistricts($input['city_id'])->pluck('id')->toArray())
            ],
            'detailed_address' => 'required|max:100'
        ], $this->getValidateMessagesWhenSaveCurrent())->after(function ($validator) {
            $managedGroupsInfo = $this->userProfileHelper->getManagedGroups();

            if (empty($managedGroupsInfo)) {
                $validator->errors()->add('no_internal_org_id', '当前没有主运营机构');
            }

        })->validate();
    }

    private function getValidateMessagesWhenSaveCurrent()
    {
        return [
            'name.required' => '运营组织名称必须存在',
            'name.max'  => '运营组织长度不可超过:max',
            'name.unique'  => '当前运营组织名称重复',
            'icon.max' => '图标路径过长',
            'manager_id.required' => '运营管理员必须填写',
            'manager_id.in'  => '运营管理员不属于当前组织',
            'province_id.required' => '省份信息必须填写',
            'province_id.numeric' => '省份ID必须是数字',
            'province_id.exists' => '身份ID不存在',
            'city_id.required' => '城市信息必须填写',
            'city_id.numeric' => '城市ID必须是数字',
            'city_id.in' => '城市ID不属于当前省份',
            'district_id.required' => '区县信息必须填写',
            'district_id.numeric' => '区县ID必须是数字',
            'district_id.in' => '区县ID不属于当前城市',
            'detailed_address.required' => '详细地址不可为空',
            'detailed_address.max'  => '详细地址长度不可超过:max',
        ];
    }

    private function validateWhenSaveNewDepartment(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])->where('parent_id', $input['parent_id']);
                })
            ],
            'parent_id' => [
                'required',
                'numeric',
                Rule::in($this->getAllIllegalGroups())
            ],
            'group_type' => [
                'required',
                'numeric',
                Rule::in([UserGroup::$GROUP_TYPE_INTERNAL_ORGANIZATION, UserGroup::$GROUP_TYPE_INTERNAL_DEPARTMENT])
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenCreateNewDepartment())->after(function ($validator) {

        })->validate();
    }

    private function getAllIllegalGroups()
    {
        if ($this->userProfileHelper->user()->isSuper()) {
            $managedGroups = $this->userProfileHelper->getManagedGroups();

            return collect($managedGroups['managedGroups'])->pluck('id')->toArray();
        }

        return [];
    }

    private function getValidateMessagesWhenCreateNewDepartment()
    {
        return [
            'name.required' => '部门名称必须存在',
            'name.max'  => '部门名称长度不可超过:max',
            'name.unique'  => '相同上级组织下，部门名称不可重复',
            'parent_id.required' => '必须存在上级部门',
            'parent_id.numeric' => '上级部门ID必须是整数',
            'parent_id.in' => '上级部门ID不合法，只能是内部部门或组织，不可为合作伙伴',
            'group_type.required' => '必须存在部门类型',
            'group_type.numeric' => '部门类型格式不合法',
            'group_type.in' => '部门类型只能是内部部门或组织，不可为合作伙伴',
        ];
    }

    private function validateWhenSaveUpdateDepartment(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])->where('parent_id', $input['parent_id'])->where('id', '<>', $input['id']);
                })
            ],
            'parent_id' => [
                'required',
                'numeric',
                Rule::in($this->getAllIllegalGroupsExceptSelf($input['id']))
            ],
            'group_type' => [
                'required',
                'numeric',
                Rule::in([UserGroup::$GROUP_TYPE_INTERNAL_ORGANIZATION, UserGroup::$GROUP_TYPE_INTERNAL_DEPARTMENT])
            ],
            'manager_id' => [
                'numeric',
                Rule::in(UserGroup::findOrFail($input['id'])->managedUsers()
                    ->where('user_active', User::$USER_STATUS_ACTIVE)->get()
                    ->pluck('id')->toArray())
            ],
            'sort_order' => 'required|numeric'
        ], $this->getValidateMessagesWhenSaveUpdateDepartment())->after(function ($validator) {

        })->validate();
    }

    private function getValidateMessagesWhenSaveUpdateDepartment()
    {
        return [
            'name.required' => '部门名称必须存在',
            'name.max'  => '部门名称长度不可超过:max',
            'name.unique'  => '相同上级组织下，部门名称不可重复',
            'parent_id.required' => '必须存在上级部门',
            'parent_id.numeric' => '上级部门ID必须是整数',
            'parent_id.in' => '上级部门ID不合法，只能是内部部门或组织，不可为合作伙伴',
            'group_type.required' => '必须存在部门类型',
            'group_type.numeric' => '部门类型格式不合法',
            'group_type.in' => '部门类型只能是内部部门或组织，不可为合作伙伴',
            'manager_id.numeric' => '部门负责人格式不合法',
            'manager_id.in' => '部门负责人只能是该部门的员工',
        ];
    }

    private function getAllIllegalGroupsExceptSelf($currentGroupId)
    {
        $allIllegalGroupIds = $this->getAllIllegalGroups();

        $countGroupIds = count($allIllegalGroupIds);

        for ($i=0; $i<$countGroupIds; $i++) {
            if ($allIllegalGroupIds[$i] == $currentGroupId) {
                unset($allIllegalGroupIds[$i]);
                break;
            }
        }

        return array_values($allIllegalGroupIds);
    }

    private function validateWhenSaveNewPartnerGroup(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('group_type', UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE)
                        ->whereNull('parent_id');
                })
            ],
            'business_code' => 'max:100',
            'partner_group_type_id' => [
                'required',
                'numeric',
                Rule::in(collect($this->partnerGroupTypeService->getPartnerGroupTypes([
                    'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
                ], false))->pluck('id')->toArray())
            ],
            'icon' => 'max:200',
            'manager_name' => 'max:50',
            'manager_nickname' => 'max:25',
            'manager_mobile' => 'required|max:30',
            'manager_password' => 'required|max:20',
            'province_id' => 'required|numeric|exists:provinces,id',
            'city_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getProvinceCities($input['province_id'])->pluck('id')->toArray())
            ],
            'district_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getCityDistricts($input['city_id'])->pluck('id')->toArray())
            ],
            'detailed_address' => 'required|max:100'
        ], $this->getValidateMessagesWhenCreateNewPartnerGroup())->after(function ($validator) use($input) {
            if ($input['manager_password'] !== $input['manager_password_again']) {
                $validator->errors()->add('manager_password_again', '两次输入密码不一致');
            }
            if (!$this->partnerGroupTypeService->hasPermission($input['partner_group_type_id']))  {
                $validator->errors()->add('partner_group_type_id.no_permission', '尚未设置该单位对应的合作伙伴类型的默认权限');
            }
        })->validate();
    }

    private function getValidateMessagesWhenCreateNewPartnerGroup()
    {
        return [
            'name.required' => '合作伙伴名称必须存在',
            'name.max'  => '合作伙伴名称长度不可超过:max',
            'name.unique'  => '当前合作伙伴名称重复',
            'partner_group_type_id.required' => '合作伙伴类型ID必须存在',
            'partner_group_type_id.numeric' => '合作伙伴类型ID必须是数字',
            'partner_group_type_id.in' => '合作伙伴类型ID值无效',
            'manager_name.max' => '管理员登录名过长，不可超过:max',
            'manager_nickname.max' => '管理员昵称过长，不可超过:max',
            'manager_mobile.max' => '管理员手机号过长，不可超过:max',
            'manager_mobile.required' => '管理员手机号不可为空',
            'manager_password.max' => '管理员密码过长，不可超过:max',
            'manager_password.required' => '管理员密码不可为空',
            'icon.max' => '图标路径过长',
            'business_code.max' => '营业执照号过长，不可超过:max',
            'province_id.required' => '省份信息必须填写',
            'province_id.numeric' => '省份ID必须是数字',
            'province_id.exists' => '身份ID不存在',
            'city_id.required' => '城市信息必须填写',
            'city_id.numeric' => '城市ID必须是数字',
            'city_id.in' => '城市ID不属于当前省份',
            'district_id.required' => '区县信息必须填写',
            'district_id.numeric' => '区县ID必须是数字',
            'district_id.in' => '区县ID不属于当前城市',
            'detailed_address.required' => '详细地址不可为空',
            'detailed_address.max'  => '详细地址长度不可超过:max',
        ];
    }

    private function validateWhenSaveUpdatePartnerGroup(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('group_type', UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE)
                        ->where('id', '<>', $input['id'])
                        ->whereNull('parent_id');
                })
            ],
            'business_code' => 'max:100',
            'partner_group_type_id' => [
                'required',
                'numeric',
                Rule::in(collect($this->partnerGroupTypeService->getPartnerGroupTypes([
                    'groupType'=>UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
                ], false))->pluck('id')->toArray())
            ],
            'icon' => 'max:200',
            'manager_name' => 'max:50',
            'manager_nickname' => 'max:25',
            'manager_mobile' => 'required|max:30',
            'manager_password' => 'required|max:20',
            'province_id' => 'required|numeric|exists:provinces,id',
            'city_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getProvinceCities($input['province_id'])->pluck('id')->toArray())
            ],
            'district_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getCityDistricts($input['city_id'])->pluck('id')->toArray())
            ],
            'detailed_address' => 'required|max:100'
        ], $this->getValidateMessagesWhenSavePartnerGroup())->after(function ($validator) use($input) {
            if ($input['manager_password'] !== $input['manager_password_again']) {
                $validator->errors()->add('manager_password_again', '两次输入密码不一致');
            }
            if (!$this->partnerGroupTypeService->hasPermission($input['partner_group_type_id']))  {
                $validator->errors()->add('partner_group_type_id.no_permission', '尚未设置该单位对应的合作伙伴类型的默认权限');
            }
        })->validate();
    }

    private function getValidateMessagesWhenSavePartnerGroup()
    {
        return [
            'name.required' => '合作伙伴名称必须存在',
            'name.max'  => '合作伙伴名称长度不可超过:max',
            'name.unique'  => '当前合作伙伴名称重复',
            'partner_group_type_id.required' => '合作伙伴类型ID必须存在',
            'partner_group_type_id.numeric' => '合作伙伴类型ID必须是数字',
            'partner_group_type_id.in' => '合作伙伴类型ID值无效',
            'manager_name.max' => '管理员登录名过长，不可超过:max',
            'manager_nickname.max' => '管理员昵称过长，不可超过:max',
            'manager_mobile.max' => '管理员手机号过长，不可超过:max',
            'manager_mobile.required' => '管理员手机号不可为空',
            'manager_password.max' => '管理员密码过长，不可超过:max',
            'manager_password.required' => '管理员密码不可为空',
            'icon.max' => '图标路径过长',
            'business_code.max' => '营业执照号过长，不可超过:max',
            'province_id.required' => '省份信息必须填写',
            'province_id.numeric' => '省份ID必须是数字',
            'province_id.exists' => '身份ID不存在',
            'city_id.required' => '城市信息必须填写',
            'city_id.numeric' => '城市ID必须是数字',
            'city_id.in' => '城市ID不属于当前省份',
            'district_id.required' => '区县信息必须填写',
            'district_id.numeric' => '区县ID必须是数字',
            'district_id.in' => '区县ID不属于当前城市',
            'detailed_address.required' => '详细地址不可为空',
            'detailed_address.max'  => '详细地址长度不可超过:max',
        ];
    }

    private function validateWhenSaveNewSimpleGroup(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('group_type', UserGroup::$GROUP_TYPE_USER)
                        ->whereNull('parent_id');
                })
            ],
            'partner_group_type_id' => [
                'required',
                'numeric',
                Rule::in(collect($this->partnerGroupTypeService->getPartnerGroupTypes([
                    'groupType'=>UserGroup::$GROUP_TYPE_USER
                ], false))->pluck('id')->toArray())
            ],
            'icon' => 'max:200',
            'manager_name' => 'max:50',
            'manager_nickname' => 'max:25',
            'manager_mobile' => 'required|max:30',
            'manager_password' => 'required|max:20',
            'province_id' => 'required|numeric|exists:provinces,id',
            'city_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getProvinceCities($input['province_id'])->pluck('id')->toArray())
            ],
            'district_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getCityDistricts($input['city_id'])->pluck('id')->toArray())
            ],
            'detailed_address' => 'required|max:100'
        ], $this->getValidateMessagesWhenCreateNewSimpleGroup())->after(function ($validator) use($input) {
            if ($input['manager_password'] !== $input['manager_password_again']) {
                $validator->errors()->add('manager_password_again', '两次输入密码不一致');
            }
            if (!$this->partnerGroupTypeService->hasPermission($input['partner_group_type_id']))  {
                $validator->errors()->add('partner_group_type_id.no_permission', '尚未设置该个人伙伴对应的用户组类型的默认权限');
            }
        })->validate();
    }

    private function getValidateMessagesWhenCreateNewSimpleGroup()
    {
        return [
            'name.required' => '个人伙伴名称必须存在',
            'name.max'  => '个人伙伴名称长度不可超过:max',
            'name.unique'  => '当前个人伙伴名称重复',
            'partner_group_type_id.required' => '合作个人伙伴类型ID必须存在',
            'partner_group_type_id.numeric' => '合作个人伙伴类型ID必须是数字',
            'partner_group_type_id.in' => '合作个人伙伴类型ID值无效',
            'manager_name.max' => '管理员登录名过长，不可超过:max',
            'manager_nickname.max' => '管理员昵称过长，不可超过:max',
            'manager_mobile.max' => '管理员手机号过长，不可超过:max',
            'manager_mobile.required' => '管理员手机号不可为空',
            'manager_password.max' => '管理员密码过长，不可超过:max',
            'manager_password.required' => '管理员密码不可为空',
            'icon.max' => '图标路径过长',
            'province_id.required' => '省份信息必须填写',
            'province_id.numeric' => '省份ID必须是数字',
            'province_id.exists' => '身份ID不存在',
            'city_id.required' => '城市信息必须填写',
            'city_id.numeric' => '城市ID必须是数字',
            'city_id.in' => '城市ID不属于当前省份',
            'district_id.required' => '区县信息必须填写',
            'district_id.numeric' => '区县ID必须是数字',
            'district_id.in' => '区县ID不属于当前城市',
            'detailed_address.required' => '详细地址不可为空',
            'detailed_address.max'  => '详细地址长度不可超过:max',
        ];
    }

    private function validateWhenSaveUpdateSimpleGroup(Array $input)
    {
        return Validator::make($input, [
            'name' => [
                'required',
                'max:50',
                Rule::unique('user_groups')->where(function ($query) use($input) {
                    $query->where('name', $input['name'])
                        ->where('group_type', UserGroup::$GROUP_TYPE_USER)
                        ->where('id', '<>', $input['id'])
                        ->whereNull('parent_id');
                })
            ],
            'partner_group_type_id' => [
                'required',
                'numeric',
                Rule::in(collect($this->partnerGroupTypeService->getPartnerGroupTypes([
                    'groupType'=>UserGroup::$GROUP_TYPE_USER
                ], false))->pluck('id')->toArray())
            ],
            'icon' => 'max:200',
            'manager_name' => 'max:50',
            'manager_nickname' => 'max:25',
            'manager_mobile' => 'required|max:30',
            'manager_password' => 'required|max:20',
            'province_id' => 'required|numeric|exists:provinces,id',
            'city_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getProvinceCities($input['province_id'])->pluck('id')->toArray())
            ],
            'district_id' => [
                'required',
                'numeric',
                Rule::in($this->cityService->getCityDistricts($input['city_id'])->pluck('id')->toArray())
            ],
            'detailed_address' => 'required|max:100'
        ], $this->getValidateMessagesWhenSaveSimpleGroup())->after(function ($validator) use($input) {
            if ($input['manager_password'] !== $input['manager_password_again']) {
                $validator->errors()->add('manager_password_again', '两次输入密码不一致');
            }
            if (!$this->partnerGroupTypeService->hasPermission($input['partner_group_type_id']))  {
                $validator->errors()->add('partner_group_type_id.no_permission', '尚未设置该个人伙伴对应的用户组类型的默认权限');
            }
        })->validate();
    }

    private function getValidateMessagesWhenSaveSimpleGroup()
    {
        return [
            'name.required' => '个人合作伙伴名称必须存在',
            'name.max'  => '个人合作伙伴名称长度不可超过:max',
            'name.unique'  => '当前个人合作伙伴名称重复',
            'partner_group_type_id.required' => '个人合作伙伴类型ID必须存在',
            'partner_group_type_id.numeric' => '个人合作伙伴类型ID必须是数字',
            'partner_group_type_id.in' => '个人合作伙伴类型ID值无效',
            'manager_name.max' => '管理员登录名过长，不可超过:max',
            'manager_nickname.max' => '管理员昵称过长，不可超过:max',
            'manager_mobile.max' => '管理员手机号过长，不可超过:max',
            'manager_mobile.required' => '管理员手机号不可为空',
            'manager_password.max' => '管理员密码过长，不可超过:max',
            'manager_password.required' => '管理员密码不可为空',
            'icon.max' => '图标路径过长',
            'province_id.required' => '省份信息必须填写',
            'province_id.numeric' => '省份ID必须是数字',
            'province_id.exists' => '身份ID不存在',
            'city_id.required' => '城市信息必须填写',
            'city_id.numeric' => '城市ID必须是数字',
            'city_id.in' => '城市ID不属于当前省份',
            'district_id.required' => '区县信息必须填写',
            'district_id.numeric' => '区县ID必须是数字',
            'district_id.in' => '区县ID不属于当前城市',
            'detailed_address.required' => '详细地址不可为空',
            'detailed_address.max'  => '详细地址长度不可超过:max',
        ];
    }

    private function validateWhenDeleteDepartment(Array $input)
    {
        return Validator::make($input, [
                'id' => [
                    'required',
                    Rule::exists('user_groups')->where(function ($query) {
                        $query->whereIn('group_type', [
                            UserGroup::$GROUP_TYPE_INTERNAL_ORGANIZATION,
                            UserGroup::$GROUP_TYPE_INTERNAL_DEPARTMENT
                        ]);
                    })
                ]
            ], [
                'id.required' => '必须传入部门ID',
                'id.exists' => '该部门ID参数有误，不存在'
            ])->after(function ($validator) use($input) {
                if ($this->userGroupService->hasChildren($input['id'])) {
                    $validator->errors()->add('id', '该部门存在子用户组，不可删除');
                }
                if ($this->userGroupService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该部门存在其它关联，不可删除');
                }
            })->validate();
    }

    private function validateWhenDeletePartnerGroup(Array $input)
    {
        return Validator::make($input, [
                'id' => [
                    'required',
                    Rule::exists('user_groups')->where(function ($query) {
                        $query->whereIn('group_type', [
                            UserGroup::$GROUP_TYPE_EXTERNAL_ENTERPRISE
                        ]);
                    })
                ]
            ], [
                'id.required' => '必须传入合作单位ID',
                'id.exists' => '该合作单位ID参数有误，不存在'
            ])->after(function ($validator) use($input) {
                if ($this->userGroupService->hasChildren($input['id'])) {
                    $validator->errors()->add('id', '该合作单位存在子单位，不可删除');
                }
                if ($this->userGroupService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该合作单位存在其它关联，不可删除');
                }
            })->validate();
    }

    private function validateWhenDeleteSimpleGroup(Array $input)
    {
        return Validator::make($input, [
                'id' => [
                    'required',
                    Rule::exists('user_groups')->where(function ($query) {
                        $query->whereIn('group_type', [
                            UserGroup::$GROUP_TYPE_USER
                        ]);
                    })
                ]
            ], [
                'id.required' => '必须传入合作单位ID',
                'id.exists' => '该合作单位ID参数有误，不存在'
            ])->after(function ($validator) use($input) {
                if ($this->userGroupService->hasChildren($input['id'])) {
                    $validator->errors()->add('id', '该合作单位存在子单位，不可删除');
                }
                if ($this->userGroupService->hasConstrait($input['id'])) {
                    $validator->errors()->add('id', '该合作单位存在其它关联，不可删除');
                }
            })->validate();
    }
}
